﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Data.SqlClient;
using FaultBackService.Shared;

namespace FaultBackService
{
    /// <summary>
    /// 服务运行帮助静态类
    /// </summary>
    static class ServiceHelper
    {
        //SCADA数据服务器对时计时器
        static Timer checkTimeForScadaTicker;
        //Fault数据服务器对时计时器
        static Timer checkTimeForFaultTicker;
        //10分钟实时故障事务计时器
        static Timer realTimeFaultTimer;
        //每日实时故障事务计时器
        static Timer realTimeFaultDailyTimer;
        //趋势数据每日分析计时器
        static Timer trendDailyTimer;

        //获取SCADA最新数据时间的计时器
        static Timer lastTimeOfScadaDataTicker;


        private static object thisLock = new object();
        /// <summary>
        /// SCADA数据库最新的十分钟数据时间
        /// </summary>
        //static DateTime _lastTenMeanTimeOfScada;

        public static void Start()
        {

            //StartNewTimerForTrend();
            

            //释放旧的Timer，开启新的Timer
            //实时故障实时分析Timer
            StartNewTimerForRealTimeFault();

            //实时故障每日分析Timer
            StartNewTimerForRealTimeFaultDaily();

            //趋势数据每日分析Timer
            StartNewTimerForTrend();

            //Console.ReadLine();


        }



        /// <summary>
        /// 启动实时故障的实时分析Timer
        /// </summary>
        public static void StartNewTimerForRealTimeFault()
        {
            /* 关闭之前的Timer */
            if (realTimeFaultTimer != null)
            {
                realTimeFaultTimer.Dispose();
                lock (thisLock)
                {
                    new Log().EndTimerForRealTimeFault();
                }
            }

            /* 开始新的Timer */
            try
            {
                SetLastTenMeanTimeOfScada();

                new Log().TenMeanRealTime_ReadLastSCADATimeSuccess(Global.CurrentTenMeanTimeOfScada.ToString());

                lock (thisLock)
                {
                    new Log().StartNewTimerForRealTimeFault();
                    Global.RealTimeCount = 0;
                }
                //执行实时故障分析的实时事务，10分钟一次，隔10秒后首次执行
                realTimeFaultTimer = new Timer(new ThreadProc().DoRealTimeFaultTransactionOnRealTime, null, 10000, 600000);  //30000, 600000
            }
            catch (Exception e)
            {
                new Log().TenMeanRealTime_ReadLastSCADATimeError(e.Message);
                Thread.Sleep(600000);
                StartNewTimerForRealTimeFault();
            }
            
            
        }

        /// <summary>
        /// 启动实时故障的每日分析Timer
        /// </summary>
        public static void StartNewTimerForRealTimeFaultDaily()
        {
            //连接故障数据库，获取最新的实时故障每日分析的日期
            try
            {
                SetLastRealTimeDailyDate();

                //执行实时故障分析的每日事务，1小时一次，隔20秒首次执行
                realTimeFaultDailyTimer = new Timer(new ThreadProc().DoRealTimeFaultTransactionOnDaily, null, 20000, 3600000);  //30000, 3600000
                lock (thisLock)
                {
                    new Log().StartNewTimerForRealTimeFaultDaily();   //写入日志：成功开启计时器
                }
            }
            catch (Exception)
            {
                Thread.Sleep(600000);   //发生异常，等待十分钟后再次运行
                StartNewTimerForRealTimeFaultDaily();
            }
        }
        /// <summary>
        /// 启动趋势数据每日分析Timer，会抛出异常
        /// </summary>
        public static void StartNewTimerForTrend()
        {

            //连接故障数据库，获取最新的趋势分析日期
            try
            {
                SetLastTrendDailyDate();   //获取已趋势分析的最新事件，用来判断

                //执行趋势数据每日分析，1小时1次，隔半分钟首次执行
                trendDailyTimer = new Timer(new ThreadProc().DoTrendTransactionOnDaily, null, 30000, 3600000);  //30000, 3600000
            }
            catch (Exception)
            {
                Thread.Sleep(600000);
                StartNewTimerForTrend();
            }
        }

        /// <summary>
        /// 获取趋势数据每日分析的最新日期
        /// </summary>
        private static void SetLastTrendDailyDate()
        {
            try
            {
                var time = new BLL.TrendStableValue().GetLastTimeStamp();   //没有数据，则返回默认时间：1970-1-1
                new Log().Trend_ReadLastDateSuccess(time.ToString());
                Global.LastTrendDailyDate = time;
            }
            catch (SqlException e)
            {
                new Log().Trend_ReadLastDateError(e.Message);
                throw;
            }
        }




        /// <summary>
        /// 获取SCADA十分钟数据最新时间，修改数据库连接状态
        /// </summary>
        private static void SetLastTenMeanTimeOfScada()
        {
            //连接SCADA数据库
            new Log().StartConnectSCADA();
            //try
            //{
                var time = new BLL.t_TurbDataGeneric().GetLastTimeStamp();
#if DEBUG
                //time = new DateTime(2016, 12, 15, 0, 35, 0);
#endif

                //赋值 Global.CurrentTenMeanTimeOfScada，写入日志
                Global.CurrentTenMeanTimeOfScada = time;

                if (Global.CurrentTenMeanTimeOfScada == Global.DefaultTime)
                    new Log().DataIsEmpty();
                else
                    new Log().GetScadaLastTenMeanTimeSuccess(Global.CurrentTenMeanTimeOfScada);

                //修改数据库状态(正常/异常)
                if (Global.SCADAConnectionState == false) Global.SCADAConnectionState = true;
            //}
            //catch (SqlException e)
            //{
            //    if (Global.SCADAConnectionState) Global.SCADAConnectionState = false;
            //    new Log().ReadSCADAFail(e.Message);
            //    throw e;
            //}
        }

        /// <summary>
        /// 连接故障数据库，获取最新的实时故障每日分析的日期
        /// </summary>
        private static void SetLastRealTimeDailyDate()
        {
            //1. 写日志：开始...
            new Log().StartConnectFault();

            //2. 获取RealTimeFaultDataDaily的最新日期
            try
            {
                var date = new BLL.RealTimeFaultDataDaily().GetLastDate();   //获取RealTimeFaultDataDaily的最新日期
                Global.LastRealTimeFaultDailyDate = date;

                //修改数据库状态(正常/异常)
                //if (Global.FaultConnectionState == false) Global.FaultConnectionState = true;
                new Log().ConnectFaultSuccess();   //写入成功日志
            }
            catch (SqlException e)
            {
                //修改数据库状态(正常/异常)
                //if (Global.FaultConnectionState == true) Global.FaultConnectionState = false;
                new Log().ConnectFaultFail(e.Message);   //写入失败日志
                throw;
            }

        }


        /// <summary>
        /// 获取最新数据时间后，周期执行实时故障分析事务，十分钟一次
        /// </summary>
        /// <param name="d"></param>
        static void CallRealTimeFaultTransaction()
        {
            //停止循环读取十分钟最新时间
            lastTimeOfScadaDataTicker.Dispose();

            //隔1分钟开始执行事务，10分钟一次
            //realTimeFaultTimer = new Timer(new ThreadProc().DoRealTimeFaultTransactionOnRealTime, null, 5000, 100);


        }

        private static void SetLastTenMeanInfo()
        {
            Models.TenMeanData tenMean = new BLL.TenMeanData().GetLastOne();
            Global.LastTenMeanInfo2.TimeStamp = tenMean == null ? Global.DefaultTime : tenMean.TimeStamp;
            Global.LastTenMeanInfo2.TurbineId = tenMean == null ? 0 : tenMean.TurbineId;
        }



    }
}
